package com.zenithmind.exam.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zenithmind.common.context.UserContext;
import com.zenithmind.common.result.Result;
import com.zenithmind.exam.pojo.dto.AnswerSubmitDTO;
import com.zenithmind.exam.pojo.entity.ExamRecord;
import com.zenithmind.exam.pojo.vo.ExamRecordVO;
import com.zenithmind.exam.service.ExamRecordService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank;
import java.util.List;

/**
 * 考试记录控制器
 * 
 * @author ZenithMind
 * @since 2024-07-01
 */
@Slf4j
@RestController
@RequestMapping("/api/exam/record")
@RequiredArgsConstructor
@Validated
@Tag(name = "考试记录管理", description = "考试记录的相关操作")
public class ExamRecordController {

    private final ExamRecordService examRecordService;

    @PostMapping("/{examId}/start")
    @Operation(summary = "开始考试", description = "学生开始参加考试")
    @PreAuthorize("hasRole('STUDENT') or hasRole('USER') or hasRole('TEACHER') or hasRole('ADMIN')")
    public Result<String> startExam(
            @Parameter(description = "考试ID") @PathVariable @NotBlank String examId,
            HttpServletRequest request) {
        String userId = UserContext.getUserId();
        String userName = UserContext.getUsername();
        String ipAddress = getClientIpAddress(request);
        String userAgent = request.getHeader("User-Agent");
        
        String examRecordId = examRecordService.startExam(examId, userId, userName, ipAddress, userAgent);
        return Result.success(examRecordId);
    }

    @PostMapping("/{recordId}/submit")
    @Operation(summary = "提交答案", description = "提交考试答案")
    @PreAuthorize("hasRole('STUDENT') or hasRole('USER') or hasRole('TEACHER') or hasRole('ADMIN')")
    public Result<Boolean> submitAnswers(
            @Parameter(description = "考试记录ID") @PathVariable @NotBlank String recordId,
            @Valid @RequestBody AnswerSubmitDTO answerSubmitDTO) {
        answerSubmitDTO.setExamRecordId(recordId);
        boolean result = examRecordService.submitAnswers(answerSubmitDTO);
        return Result.success(result);
    }

    @PostMapping("/{recordId}/finish")
    @Operation(summary = "完成考试", description = "完成考试并提交")
    @PreAuthorize("hasRole('STUDENT') or hasRole('USER') or hasRole('TEACHER') or hasRole('ADMIN')")
    public Result<Boolean> finishExam(
            @Parameter(description = "考试记录ID") @PathVariable @NotBlank String recordId) {
        boolean result = examRecordService.finishExam(recordId);
        return Result.success(result);
    }

    @GetMapping("/{recordId}")
    @Operation(summary = "获取考试记录详情", description = "根据ID获取考试记录详情")
    public Result<ExamRecordVO> getExamRecordById(
            @Parameter(description = "考试记录ID") @PathVariable @NotBlank String recordId) {
        ExamRecordVO examRecord = examRecordService.getExamRecordById(recordId);
        return Result.success(examRecord);
    }

    @GetMapping("/exam/{examId}")
    @Operation(summary = "获取考试的所有记录", description = "根据考试ID获取所有考试记录")
    @PreAuthorize("hasRole('TEACHER') or hasRole('ADMIN')")
    public Result<List<ExamRecordVO>> getExamRecordsByExamId(
            @Parameter(description = "考试ID") @PathVariable @NotBlank String examId) {
        List<ExamRecordVO> records = examRecordService.getExamRecordsByExamId(examId);
        return Result.success(records);
    }

    @GetMapping("/my-records")
    @Operation(summary = "获取我的考试记录", description = "获取当前用户的考试记录列表")
    @PreAuthorize("hasRole('STUDENT') or hasRole('USER') or hasRole('TEACHER') or hasRole('ADMIN')")
    public Result<List<ExamRecordVO>> getMyExamRecords() {
        String userId = UserContext.getUserId();
        List<ExamRecordVO> records = examRecordService.getExamRecordsByUserId(userId);
        return Result.success(records);
    }

    @GetMapping("/page")
    @Operation(summary = "分页查询考试记录", description = "分页查询考试记录列表")
    @PreAuthorize("hasRole('TEACHER') or hasRole('ADMIN')")
    public Result<IPage<ExamRecordVO>> getExamRecordPage(
            @Parameter(description = "页码") @RequestParam(defaultValue = "1") Integer pageNum,
            @Parameter(description = "每页数量") @RequestParam(defaultValue = "10") Integer pageSize,
            @Parameter(description = "考试ID") @RequestParam(required = false) String examId,
            @Parameter(description = "用户ID") @RequestParam(required = false) String userId,
            @Parameter(description = "用户姓名") @RequestParam(required = false) String userName,
            @Parameter(description = "状态") @RequestParam(required = false) Integer status) {
        
        Page<ExamRecord> page = new Page<>(pageNum, pageSize);
        IPage<ExamRecordVO> result = examRecordService.getExamRecordPage(page, examId, userId, userName, status);
        return Result.success(result);
    }

    @GetMapping("/exam/{examId}/ranking")
    @Operation(summary = "获取考试排行榜", description = "获取指定考试的排行榜")
    public Result<List<ExamRecordVO>> getExamRanking(
            @Parameter(description = "考试ID") @PathVariable @NotBlank String examId,
            @Parameter(description = "限制数量") @RequestParam(defaultValue = "50") Integer limit) {
        List<ExamRecordVO> ranking = examRecordService.getExamRanking(examId, limit);
        return Result.success(ranking);
    }

    @PostMapping("/{recordId}/rescore")
    @Operation(summary = "重新评分", description = "重新评分指定的考试记录")
    @PreAuthorize("hasRole('TEACHER') or hasRole('ADMIN')")
    public Result<Boolean> rescoreExamRecord(
            @Parameter(description = "考试记录ID") @PathVariable @NotBlank String recordId) {
        boolean result = examRecordService.rescoreExamRecord(recordId);
        return Result.success(result);
    }

    @PostMapping("/exam/{examId}/batch-rescore")
    @Operation(summary = "批量重新评分", description = "批量重新评分指定考试的所有记录")
    @PreAuthorize("hasRole('TEACHER') or hasRole('ADMIN')")
    public Result<Boolean> batchRescoreExamRecords(
            @Parameter(description = "考试ID") @PathVariable @NotBlank String examId) {
        boolean result = examRecordService.batchRescoreExamRecords(examId);
        return Result.success(result);
    }

    @DeleteMapping("/{recordId}")
    @Operation(summary = "删除考试记录", description = "删除指定的考试记录")
    @PreAuthorize("hasRole('ADMIN')")
    public Result<Boolean> deleteExamRecord(
            @Parameter(description = "考试记录ID") @PathVariable @NotBlank String recordId) {
        boolean result = examRecordService.deleteExamRecord(recordId);
        return Result.success(result);
    }

    @DeleteMapping("/batch")
    @Operation(summary = "批量删除考试记录", description = "批量删除指定的考试记录")
    @PreAuthorize("hasRole('ADMIN')")
    public Result<Boolean> batchDeleteExamRecords(
            @Parameter(description = "考试记录ID列表") @RequestBody List<String> recordIds) {
        boolean result = examRecordService.batchDeleteExamRecords(recordIds);
        return Result.success(result);
    }

    @GetMapping("/exam/{examId}/user/{userId}/check")
    @Operation(summary = "检查用户是否已参加考试", description = "检查指定用户是否已参加指定考试")
    public Result<Boolean> hasUserTakenExam(
            @Parameter(description = "考试ID") @PathVariable @NotBlank String examId,
            @Parameter(description = "用户ID") @PathVariable @NotBlank String userId) {
        boolean result = examRecordService.hasUserTakenExam(examId, userId);
        return Result.success(result);
    }

    @GetMapping("/exam/{examId}/my-record")
    @Operation(summary = "获取我在考试中的记录", description = "获取当前用户在指定考试中的记录")
    @PreAuthorize("hasRole('STUDENT') or hasRole('USER') or hasRole('TEACHER') or hasRole('ADMIN')")
    public Result<ExamRecordVO> getMyExamRecord(
            @Parameter(description = "考试ID") @PathVariable @NotBlank String examId) {
        String userId = UserContext.getUserId();
        ExamRecordVO record = examRecordService.getUserExamRecord(examId, userId);
        return Result.success(record);
    }

    @GetMapping("/exam/{examId}/statistics")
    @Operation(summary = "获取考试记录统计", description = "获取指定考试的记录统计信息")
    @PreAuthorize("hasRole('TEACHER') or hasRole('ADMIN')")
    public Result<ExamRecordVO> getExamRecordStatistics(
            @Parameter(description = "考试ID") @PathVariable @NotBlank String examId) {
        ExamRecordVO statistics = examRecordService.getExamRecordStatistics(examId);
        return Result.success(statistics);
    }

    @GetMapping("/exam/{examId}/export")
    @Operation(summary = "导出考试记录", description = "导出指定考试的所有记录")
    @PreAuthorize("hasRole('TEACHER') or hasRole('ADMIN')")
    public Result<List<ExamRecordVO>> exportExamRecords(
            @Parameter(description = "考试ID") @PathVariable @NotBlank String examId) {
        List<ExamRecordVO> records = examRecordService.exportExamRecords(examId);
        return Result.success(records);
    }

    @PostMapping("/handle-timeout")
    @Operation(summary = "处理超时考试", description = "处理所有超时的考试记录")
    @PreAuthorize("hasRole('ADMIN')")
    public Result<Boolean> handleTimeoutExams() {
        examRecordService.handleTimeoutExams();
        return Result.success(true);
    }

    /**
     * 获取客户端IP地址
     */
    private String getClientIpAddress(HttpServletRequest request) {
        String xForwardedFor = request.getHeader("X-Forwarded-For");
        if (xForwardedFor != null && !xForwardedFor.isEmpty() && !"unknown".equalsIgnoreCase(xForwardedFor)) {
            return xForwardedFor.split(",")[0].trim();
        }
        
        String xRealIp = request.getHeader("X-Real-IP");
        if (xRealIp != null && !xRealIp.isEmpty() && !"unknown".equalsIgnoreCase(xRealIp)) {
            return xRealIp;
        }
        
        return request.getRemoteAddr();
    }
}
